package com.uniflow.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.uniflow.common.PageResult;
import com.uniflow.entity.AuditLogs;
import com.uniflow.entity.User;
import com.uniflow.mapper.RoleMapper;
import com.uniflow.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 用户服务类
 */
@Service
@Transactional
public class UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private AuditLogService auditLogService;
    
    @Autowired
    private PermissionService permissionService;
    
    /**
     * 根据ID查询用户
     */
    public User getUserById(String id) {
        return userMapper.selectById(id);
    }
    
    /**
     * 根据用户名查询用户
     */
    public User getUserByUsername(String username) {
        return userMapper.selectByUsername(username);
    }
    
    /**
     * 根据邮箱查询用户
     */
    public User getUserByEmail(String email) {
        return userMapper.selectByEmail(email);
    }
    
    /**
     * 查询用户及其角色信息
     */
    public User getUserWithRoles(String id) {
        return userMapper.selectWithRoles(id);
    }
    
    /**
     * 查询用户及其组织信息
     */
    public User getUserWithOrganization(String id) {
        return userMapper.selectWithOrganization(id);
    }
    
    /**
     * 分页查询用户列表
     */
    public PageResult<User> getUserList(int pageNum, int pageSize, String orgId, Integer status, String keyword) {
        PageHelper.startPage(pageNum, pageSize);
        
        List<User> users = userMapper.selectList(orgId, status, keyword);
        PageInfo<User> pageInfo = new PageInfo<>(users);
        
        return PageResult.of(pageInfo.getPageNum(), pageInfo.getPageSize(), 
                           pageInfo.getTotal(), pageInfo.getList());
    }
    
    /**
     * 根据组织ID查询用户列表
     */
    public List<User> getUsersByOrgId(String orgId) {
        return userMapper.selectByOrgId(orgId);
    }
    
    /**
     * 根据角色ID查询用户列表
     */
    public List<User> getUsersByRoleId(String roleId) {
        return userMapper.selectByRoleId(roleId);
    }
    
    /**
     * 创建用户
     */
    public User createUser(User user) {
        // 验证用户名是否已存在
        if (userMapper.existsByUsername(user.getUsername(), null)) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 验证邮箱是否已存在
        if (StringUtils.hasText(user.getEmail()) && userMapper.existsByEmail(user.getEmail(), null)) {
            throw new RuntimeException("邮箱已存在");
        }
        
        // 设置用户ID
        user.setId(UUID.randomUUID().toString().replace("-", ""));
        
        // 加密密码
        if (StringUtils.hasText(user.getPasswordHash())) {
            user.setPasswordHash(passwordEncoder.encode(user.getPasswordHash()));
        }
        
        // 设置默认状态
        if (user.getStatus() == null) {
            user.setStatus(1);
        }
        
        // 设置创建时间
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());
        
        // 保存用户
        userMapper.insert(user);
        
        // 记录审计日志
        recordAuditLog("CREATE", "USER", user.getId(), 
                      "创建用户: " + user.getUsername(), "SUCCESS", null);
        
        return user;
    }
    
    /**
     * 批量创建用户
     */
    public void createUsers(List<User> users) {
        for (User user : users) {
            // 验证用户名是否已存在
            if (userMapper.existsByUsername(user.getUsername(), null)) {
                throw new RuntimeException("用户名已存在: " + user.getUsername());
            }
            
            // 验证邮箱是否已存在
            if (StringUtils.hasText(user.getEmail()) && userMapper.existsByEmail(user.getEmail(), null)) {
                throw new RuntimeException("邮箱已存在: " + user.getEmail());
            }
            
            // 设置用户ID
            user.setId(UUID.randomUUID().toString().replace("-", ""));
            
            // 加密密码
            if (StringUtils.hasText(user.getPasswordHash())) {
                user.setPasswordHash(passwordEncoder.encode(user.getPasswordHash()));
            }
            
            // 设置默认状态
            if (user.getStatus() == null) {
                user.setStatus(1);
            }
            
            // 设置创建时间
            user.setCreatedAt(LocalDateTime.now());
            user.setUpdatedAt(LocalDateTime.now());
        }
        
        // 批量保存
        userMapper.insertBatch(users);
    }
    
    /**
     * 更新用户
     */
    public User updateUser(User user) {
        // 验证用户是否存在
        User existingUser = userMapper.selectById(user.getId());
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 验证用户名是否已被其他用户使用
        if (StringUtils.hasText(user.getUsername()) && 
            userMapper.existsByUsername(user.getUsername(), user.getId())) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 验证邮箱是否已被其他用户使用
        if (StringUtils.hasText(user.getEmail()) && 
            userMapper.existsByEmail(user.getEmail(), user.getId())) {
            throw new RuntimeException("邮箱已存在");
        }
        
        // 如果密码不为空，则加密
        if (StringUtils.hasText(user.getPasswordHash())) {
            user.setPasswordHash(passwordEncoder.encode(user.getPasswordHash()));
        }
        
        // 设置更新时间
        user.setUpdatedAt(LocalDateTime.now());
        
        // 更新用户
        userMapper.updateById(user);
        
        // 记录审计日志
        recordAuditLog("UPDATE", "USER", user.getId(), 
                      "更新用户: " + user.getUsername(), "SUCCESS", null);
        
        return userMapper.selectById(user.getId());
    }
    
    /**
     * 更新用户状态
     */
    public void updateUserStatus(String id, Integer status) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        userMapper.updateStatus(id, status);
    }
    
    /**
     * 重置用户密码
     */
    public void resetUserPassword(String id, String newPassword) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        String encodedPassword = passwordEncoder.encode(newPassword);
        userMapper.updatePassword(id, encodedPassword);
    }
    
    /**
     * 删除用户
     */
    public void deleteUser(String id) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 获取用户信息用于审计日志
        User userToDelete = userMapper.selectById(id);
        String username = userToDelete != null ? userToDelete.getUsername() : "unknown";
        
        // 清除用户角色关联
        roleMapper.clearUserRoles(id);
        
        // 删除用户
        userMapper.deleteById(id);
        
        // 记录审计日志
        recordAuditLog("DELETE", "USER", id, 
                      "删除用户: " + username, "SUCCESS", null);
    }
    
    /**
     * 批量删除用户
     */
    public void deleteUsers(List<String> ids) {
        for (String id : ids) {
            // 清除用户角色关联
            roleMapper.clearUserRoles(id);
        }
        
        // 批量删除用户
        userMapper.deleteBatch(ids);
    }
    
    /**
     * 为用户分配角色
     */
    public void assignRolesToUser(String userId, List<String> roleIds) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 清除现有角色
        roleMapper.clearUserRoles(userId);
        
        // 分配新角色
        if (roleIds != null && !roleIds.isEmpty()) {
            roleMapper.batchAssignRolesToUser(userId, roleIds);
        }
    }
    
    /**
     * 移除用户角色
     */
    public void removeRoleFromUser(String userId, String roleId) {
        roleMapper.removeRoleFromUser(userId, roleId);
    }
    
    /**
     * 检查用户名是否可用
     */
    public boolean isUsernameAvailable(String username, String excludeId) {
        return !userMapper.existsByUsername(username, excludeId);
    }
    
    /**
     * 检查邮箱是否可用
     */
    public boolean isEmailAvailable(String email, String excludeId) {
        return !userMapper.existsByEmail(email, excludeId);
    }
    
    /**
     * 检查用户是否拥有指定角色
     */
    public boolean hasRole(String userId, String roleId) {
        return roleMapper.hasRole(userId, roleId);
    }
    
    /**
     * 检查用户是否拥有指定权限
     */
    public boolean hasPermission(String userId, String permission) {
        return roleMapper.hasPermission(userId, permission);
    }
    
    /**
     * 更新用户最后同步时间
     */
    public void updateLastSyncAt(String id) {
        userMapper.updateLastSyncAt(id);
    }
    
    /**
     * 根据外部ID查询用户
     */
    public User getUserByExternalId(String externalId, String syncSource) {
        return userMapper.selectByExternalId(externalId, syncSource);
    }
    
    /**
     * 统计用户数量
     */
    public Map<String, Object> getUserStatistics() {
        // 这里可以实现用户统计逻辑
        // 例如：总用户数、活跃用户数、各组织用户数等
        Map<String, Object> statistics = new HashMap<>();
        statistics.put("totalUsers", userMapper.selectCount(null, null, null));
        statistics.put("activeUsers", userMapper.selectCount(null, 1, null));
        statistics.put("inactiveUsers", userMapper.selectCount(null, 0, null));
        return statistics;
    }
    
    /**
     * 记录审计日志
     */
    private void recordAuditLog(String action, String resourceType, String resourceId, 
                               String description, String status, String operatorId) {
        try {
            AuditLogs auditLog = new AuditLogs();
            auditLog.setUserId(operatorId);
            auditLog.setOperationType(action);
            auditLog.setResourceType(resourceType);
            auditLog.setResourceId(resourceId);
            auditLog.setOperationDesc(description);
            auditLog.setOperationResult(status);
            auditLog.setOperationTime(LocalDateTime.now());
            
            auditLogService.createAuditLog(auditLog);
        } catch (Exception e) {
            // 审计日志记录失败不应影响主业务流程
            System.err.println("记录审计日志失败: " + e.getMessage());
        }
    }
    
    /**
     * 检查用户权限
     */
    public boolean checkUserPermission(String userId, String permission) {
        // 直接使用PermissionService检查用户权限
        return permissionService.hasUserPermission(userId, permission);
    }
    
    /**
     * 获取用户权限列表
     */
    public List<String> getUserPermissions(String userId) {
        List<com.uniflow.entity.Permission> permissions = permissionService.getUserPermissions(userId);
        return permissions.stream()
                .map(com.uniflow.entity.Permission::getCode)
                .collect(java.util.stream.Collectors.toList());
    }
}